home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 9 / Night Owl CD-ROM (NOPV9) (Night Owl Publisher) (1993).ISO / 042a / 3dlib17f.zip / RTOBJ.PAS < prev    next >
Pascal/Delphi Source File  |  1993-03-15  |  34KB  |  834 lines

  1. (******************************************************************************
  2. *                                    rtObj                                    *
  3. *      please notice -                                                        *
  4. *      this unit includes both the object3d unit, and the superobj unit,      *
  5. *      and it is used with no reference to the WWToolKit window GUI library,  *
  6. *      uses project3, instead of prjWind  (It does, however, support OWL)     *
  7. ******************************************************************************)
  8. Unit rtObj;
  9.  
  10. (*******************************************************************************
  11. *                                 3D Objects                                   *
  12. *                                 ----------                                   *
  13. *                                                                              *
  14. *   A 3D object is a collection of points and lines in the 3D universe,        *
  15. *   that represent the body we want to draw on the screen.                     *
  16. *   A 3D object is allways centered around point (0, 0, 0) in the 3D universe. *
  17. *   (Its center of gravity assuming it is has a uniform weight distribution    *
  18. *    is in point (0, 0, 0)                                                     *
  19. *   At any moment during the object's life, we know it's distance from the     *
  20. *   origin, And it's rotation using reveres rotation CTM.                      *
  21. *                                                                              *
  22. *   3D Object methods:                                                         *
  23. *      constructor Open                                                        *
  24. *      destructor  CloseMe                                                     *
  25. *      procedures: Rotate, Scale, Move, Show, Hide, Load, Save                 *
  26. *                  SetToOrigin, Paint                                          *
  27. *                                                                              *
  28. *******************************************************************************)
  29.  
  30. interface
  31.  
  32. uses
  33. {$ifdef windows}
  34.     winTypes
  35.     ,winProcs
  36. {$else}
  37.     graph
  38. {$endif}
  39.     ,Ctm3d
  40.     ,hdr3d
  41.     ,project3
  42.     ;
  43.  
  44. type
  45.     f_real = file of real;
  46.  
  47.     {===================================================================}
  48.     {  Base object is the base class for 3D-objects. some functions     }
  49.     { are dummy virtual do-nothing, which are are implemented only for  }
  50.     { the descendend objects derived from BaseObject                    }
  51.     {===================================================================}
  52.  
  53.     BaseObjectPtr = ^BaseObject;
  54.     BaseObject = object
  55.        MyCtm       : Ctm;      { This CTM applied to the object gives the  }
  56.                                {  objects Position after transformations   }
  57.        Name        : String;   { Identifies the object                     }
  58.        myColor     : word;     { Main color for the object                 }
  59.        Location    : point3d;  { Central of gravity in real space          }
  60.        scrPntUpdt  : boolean;  { True if screen points updated             }
  61.  
  62.        constructor open(myName : string; color : word);
  63.        destructor  CloseMe; virtual;
  64. {$ifdef windows}
  65.        procedure   show(dc : hdc); virtual;
  66.        procedure   hide(dc : hdc); virtual;
  67.        procedure   paint(dc : hdc); virtual; {in specified color}
  68. {$else}
  69.        procedure   show; virtual;
  70.        procedure   hide; virtual;
  71.        procedure   paint; virtual; {in specified color}
  72. {$endif}
  73.        procedure   updateScreenPoints; virtual; {transform object 3D -> 2D}
  74.        procedure   move(axis : axisType; by : real); virtual;
  75.        procedure   translate(dx, dy, dz : integer); virtual;
  76.                {multy dimentional move in 1 call}
  77.        procedure   scale(axis : axisType; factor : real); virtual;
  78.        procedure   allScale(sx, sy, sz : real); virtual;
  79.                {multy dimentional scale in 1 call}
  80.        procedure   rotate(axis : axisType; deg : real); virtual;
  81.  
  82.        procedure   goto3dPos(x, y, z : real); virtual; {translate to absolute place}
  83.        procedure   setToOrigin; virtual;
  84.                {translate to 0,0,0, update points, and set myCtm to unit}
  85.        procedure   calcLocation; virtual; {set Location to central gravity}
  86.        procedure   deleteTransform; virtual; {set MyCtm to unit}
  87.  
  88.        function load : word; virtual; {from disk}
  89.        function save : word; virtual; {to   disk}
  90.        procedure writeMe(var elementFile : f_real); virtual; {to disk .. without opening file..}
  91.        procedure readMe(var elementFile : f_real); virtual;
  92.     end;
  93.  
  94.     {===================================================================}
  95.     { Obj3d is an object which represents a 3-D object with a poligon  }
  96.     {  mesh.                                                           }
  97.     {===================================================================}
  98.  
  99.     Obj3dPtr = ^Obj3d;
  100.     Obj3d = object(BaseObject)
  101.        Points      : array[1..MaxPoints] of point3d;
  102.        Lines       : array[1..MaxLines]   of Line3d;
  103.        scrPoints   : array[1..MaxPoints] of screenPoints;
  104.        NumOfLines  : integer;
  105.        NumOfPoints : integer;
  106.        ReverseRot  : Ctm;  { Saves only the reverse rotations }
  107.        unReverseRot: Ctm;  { reverse of the above}
  108.  
  109.        constructor open(myName : string; ref : point3d; color : word);
  110.        destructor  CloseMe; virtual;
  111. {$ifdef windows}
  112.        procedure   paint(dc : hdc); virtual; {in specified color}
  113. {$else}
  114.        procedure   paint; virtual; {in specified color}
  115. {$endif}
  116.        procedure   updateScreenPoints; virtual; {transform object 3D -> 2D}
  117.  
  118.        procedure   calcLocation; virtual; {set Location to central gravity}
  119.        procedure   setToOrigin; virtual;
  120.  
  121.        procedure writeMe(var elementFile : f_real); virtual;
  122.        procedure readMe(var elementFile : f_real); virtual;
  123.     end;
  124.  
  125. const
  126.    maxSubObjects = 15;
  127.  
  128. type
  129.     complexObjPtr = ^complexObj;
  130.     ComplexObj = object(BaseObject)
  131.        childs      : array [1..maxSubObjects] of obj3dPtr;
  132.        ctms        : array [1..maxSubObjects] of ctm;
  133.        numOfChilds : integer; {counter of # of obj3d childs}
  134.  
  135.        constructor open(myName : string; color : word);
  136.        destructor  closeMe; virtual;
  137.        procedure   updateScreenPoints; virtual;
  138.        procedure   writeMe(var elementFile : f_real); virtual;
  139.        procedure   readMe(var elementFile : f_real); virtual;
  140.        procedure   calcLocation; virtual;
  141. {$ifdef WINDOWS}
  142.        procedure   paint(dc : hdc); virtual;
  143. {$else}
  144.        procedure   paint; virtual;
  145. {$endif}
  146.        procedure   move(axis : axisType; by : real); virtual;
  147.        procedure   rotate(axis : axisType; deg : real); virtual;
  148.        procedure   scale(axis : axisType; factor : real); virtual;
  149.  
  150.        function    addSubObject(myName : string; refPoint : point3d) : word;
  151.        function    getChildPtr(index : integer) : obj3dPtr;
  152.        procedure   rotateChild(child : integer; axis : axisType;
  153.                                        deg : real);
  154.        procedure   scaleChild(child : integer; axis : axisType;
  155.                                        factor : real);
  156.        procedure   moveChild(child : integer; axis : axisType;
  157.                                by : real);
  158.     end;
  159.  
  160.  
  161. implementation
  162.  
  163.  
  164.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  165.     {                     BaseObject implementation                        }
  166.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  167.  
  168. (*******************************************************************************
  169. *                              BaseObject.Open                                 *
  170. *******************************************************************************)
  171. constructor BaseObject.Open;
  172. begin
  173.     name      := myName;
  174.     myColor   := color;
  175.     location  := ZeroPoint;
  176.     MyCtm.SetUnit;
  177. end; {baseObject.open}
  178.  
  179. (*******************************************************************************
  180. *                             BaseObject.CloseMe                               *
  181. *******************************************************************************)
  182. destructor BaseObject.CloseMe;
  183. begin
  184.     { I'm here so my children will Close-themselfs properly }
  185. end; {baseObject.closeMe}
  186.  
  187. (*******************************************************************************
  188. *                              BaseObject.move                                 *
  189. *******************************************************************************)
  190. procedure BaseObject.move(axis : axisType; by: real);
  191. begin
  192.        case axis of
  193.                x : begin
  194.                        myCtm.translateX(by);
  195.                        location.x :=location.x+by;
  196.                    end;
  197.                y : begin
  198.                        myCtm.translateY(by);
  199.                        location.y :=location.y+by;
  200.                    end;
  201.                z : begin
  202.                        myCtm.translateZ(by);
  203.                        location.z :=location.z+by;
  204.                    end;
  205.        end; {case}
  206.        scrPntUpdt := False;
  207. end; {BaseObject.move}
  208.  
  209. (*******************************************************************************
  210. *                            BaseObject.translate                              *
  211. *******************************************************************************)
  212. procedure BaseObject.translate(dx, dy, dz : integer);
  213. begin
  214.        myCtm.translate(dx,dy,dz);
  215.        location.x :=location.x+dx;
  216.        location.y :=location.y+dy;
  217.        location.z :=location.z+dz;
  218.        scrPntUpdt := False;
  219. end; {BaseObject.translate}
  220.  
  221. {use this routine when you know you need to translate more then one axis
  222.        before painting, you will use only one call, which will probably be
  223.        faster, and make your program easier to read, and maintain}
  224.  
  225. (*******************************************************************************
  226. *                              BaseObject.show                                 *
  227. *******************************************************************************)
  228. procedure BaseObject.show;
  229. {$ifdef windows}
  230. var
  231.    myPen, oldPen : HPen;
  232. {$endif}
  233. begin
  234. {$ifdef WINDOWS}
  235.     myPen := getStockObject(black_Pen);
  236.     oldPen := selectObject(dc, myPen);
  237.     paint(dc);
  238.     selectObject(dc, oldPen);
  239.     deleteObject(myPen);
  240. {$else}
  241.     setColor(myColor);
  242.     paint;
  243. {$endif}
  244. end; {baseObject.show}
  245.  
  246. (*******************************************************************************
  247. *                              BaseObject.hide                                 *
  248. *******************************************************************************)
  249. procedure BaseObject.hide;
  250. {$ifdef windows}
  251. var
  252.    myPen, oldPen : HPen;
  253. {$endif}
  254. begin
  255. {$ifdef windows}
  256.     myPen := getStockObject(white_Pen);
  257.     oldPen := selectObject(dc, myPen);
  258.     paint(dc);      {at this color}
  259.     selectObject(dc, oldPen);
  260.     deleteObject(myPen);
  261. {$else}
  262.     setColor(0); {backGround}
  263.     paint;      {at this color}
  264. {$endif}
  265. end; {baseObject.hide}
  266.  
  267. (*******************************************************************************
  268. *                              BaseObject.Paint                                *
  269. *******************************************************************************)
  270. procedure BaseObject.Paint;
  271. begin
  272.     if (not(scrPntUpdt)) then
  273.        updateScreenPoints;
  274.     { alas,  BaseObject cannot really paint becuase it does not have   }
  275.     { screen points (what a shame ...)                                 }
  276. end; {baseObject.paint}
  277.  
  278. (*******************************************************************************
  279. *                       BaseObject.UpdateScreenPoints                          *
  280. *******************************************************************************)
  281. procedure BaseObject.UpdateScreenPoints;
  282. begin
  283.     scrPntUpdt := True; { Have no screen points or any other points, so     }
  284.                         { points are already updated (I think)              }
  285. end; {updateScreenPoints}
  286.  
  287. (*******************************************************************************
  288. *                              BaseObject.scale                                *
  289. *******************************************************************************)
  290. procedure BaseObject.scale(axis : axisType; factor : real);
  291. begin
  292.        myCtm.translate(-location.x,-location.y,-location.z);
  293.        case axis of
  294.                x : myCtm.scaleX(factor);
  295.                y : myCtm.scaleY(factor);
  296.                z : myCtm.scaleZ(factor);
  297.        end; {scale}
  298.        myCtm.translate(location.x,location.y,location.z);
  299.        scrPntUpdt := False;
  300. end; {baseObject.scale}
  301.  
  302. (*******************************************************************************
  303. *                            BaseObject.allScale                               *
  304. *******************************************************************************)
  305. procedure BaseObject.allScale(sx,sy,sz : real);
  306. begin
  307.     myCtm.translate(-location.x, -location.y, -location.z);
  308.     myCtm.scale(sx,sy,sz);
  309.     myCtm.translate(location.x, location.y, location.z);
  310.     scrPntUpdt := False;
  311. end; {allScale}
  312. {call this routine to scale more then one axis at a time, with a single call}
  313.  
  314. (*******************************************************************************
  315. *                            BaseObject.goto3dPos                              *
  316. *******************************************************************************)
  317. procedure BaseObject.goto3dPos;
  318. begin
  319.        translate(round(x - location.x), round(y - location.y)
  320.                        , round(z - location.z));
  321. end; {baseObject.goto3dPos}
  322.  
  323. (*******************************************************************************
  324. *                           BaseObject.setToOrigin                             *
  325. *******************************************************************************)
  326. procedure BaseObject.setToOrigin;
  327. begin
  328.     goto3dPos(0, 0, 0);
  329.     myCtm.setUnit;
  330.     location := zeroPoint;
  331. end; {BaseObject.setToOrign}
  332.  
  333. (*******************************************************************************
  334. *                          BaseObject.CalcLocation                             *
  335. *******************************************************************************)
  336. procedure BaseObject.CalcLocation;
  337. begin
  338.     location := zeroPoint; { What else could it be when there are no points ?}
  339. end; {baseObject.calcLocation}
  340.  
  341. (*******************************************************************************
  342. *                         BaseObject.deleteTransform                           *
  343. *******************************************************************************)
  344. procedure BaseObject.deleteTransform;
  345. begin
  346.     myCtm.setUnit;
  347.     scrPntUpdt := false;
  348. end; {baseObject.deleteTransform}
  349.  
  350. (******************************************************************************
  351. *                              BaseObject.rotate                              *
  352. ******************************************************************************)
  353. procedure BaseObject.rotate;
  354. begin
  355.        myCtm.translate(-location.x,-location.y,-location.z);
  356.        case axis of
  357.                x :     myCtm.rotateX(deg);
  358.                y :     myCtm.rotateY(deg);
  359.                z :     myCtm.rotateZ(deg);
  360.        end; {case}
  361.        myCtm.translate(location.x,location.y,location.z);
  362.  
  363.        {rotation means : go to origin (translate -location),
  364.                          rotate       (rotate axis degrees),
  365.                          go to prev pos (translate location);
  366.        }
  367.  
  368.        scrPntUpdt := False;
  369. end; {BaseObject.rotate, see interface for comments}
  370.  
  371. (******************************************************************************
  372. *                               baseObject.load                               *
  373. ******************************************************************************)
  374. function baseObject.load;
  375. var
  376.     elementFile : f_real;
  377.     errC       : word;
  378. begin
  379.     {$i-} {supposed to be so, just making sure}
  380.     assign(elementFile,name);
  381.     reset(elementFile); {o.k. open it}
  382.     errC := ioResult;
  383.     load := errC;
  384.     if (errC = 0) then begin
  385.        readMe(elementFile);
  386.        errC := ioResult;
  387.        load := errC;
  388.        close(elementFile);
  389.        calcLocation;
  390.        scrPntUpdt := false;
  391.     end; {if}
  392. end; { baseObject.load}
  393.  
  394. (******************************************************************************
  395. *                               baseObject.save                               *
  396. ******************************************************************************)
  397. function baseObject.save;
  398. var
  399.     elementFile : f_real;
  400.     errC       : word;
  401. begin
  402.     {$i-} {supposed to be so, just making sure}
  403.     assign(elementFile,name);
  404.     rewrite(elementFile); {o.k. open it}
  405.     errC := ioResult;
  406.     save := errC;
  407.     if (errC = 0) then begin
  408.        writeMe(elementFile);
  409.        errC := ioResult; save := errC;
  410.        close(elementFile);
  411.     end; {if}
  412. end; {baseObject.save}
  413.  
  414. (******************************************************************************
  415. *                             baseObject.writeMe                              *
  416. ******************************************************************************)
  417. procedure baseObject.writeMe;
  418. begin
  419.    {override by descendents }
  420. end; {baseObject.writeMe}
  421.  
  422. (******************************************************************************
  423. *                              baseObject.readMe                              *
  424. ******************************************************************************)
  425. procedure baseObject.readMe;
  426. begin
  427.    {override by descendents }
  428. end; {baseObject.readMe}
  429.  
  430.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  431.     {                        Obj3d implementation                          }
  432.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  433.  
  434.  
  435. (*******************************************************************************
  436. *                                 Obj3d.open                                   *
  437. *******************************************************************************)
  438. constructor Obj3d.open;
  439. begin
  440.     BaseObject.Open(myName, color);
  441.     scrPntUpdt := False; {not calculated yet}
  442.     numOfLines := 0;
  443.     numOfPoints := 0;
  444.     myCtm.setUnit; {initialize to unit matrix}
  445.     reverseRot.setUnit;
  446.     unReverseRot.setUnit;
  447. end; {Obj3d.open}
  448.  
  449. (*******************************************************************************
  450. *                               Obj3d.CloseMe                                  *
  451. *******************************************************************************)
  452. destructor Obj3d.CloseMe;
  453. begin
  454. end;  {Obj3d.Close}
  455.  
  456.  
  457. (*******************************************************************************
  458. *                          Obj3d.updateScreenPoints                            *
  459. *******************************************************************************)
  460. procedure Obj3d.updateScreenPoints;
  461. var i : integer;
  462.     p : point3d;
  463. begin
  464.     for i := 1 to numOfPoints do begin
  465.        myCtm.transform(p,points[i]); {transform by ctm}
  466.        calcPoint(p, scrPoints[i]);
  467.     end; {for}
  468.     scrPntUpdt := True; {make sure for next time..}
  469.            {make all points ready}
  470. end; {obj3d.updateScreenPoints}
  471.  
  472. (*******************************************************************************
  473. *                                Obj3d.paint                                   *
  474. *******************************************************************************)
  475. procedure Obj3d.paint;
  476. {do the actual painting here}
  477. var
  478.     i : integer;
  479. begin
  480.     if ((numOfPoints = 0) or (numOfLines = 0)) then exit;
  481.     if (not(scrPntUpdt)) then
  482.        updateScreenPoints;
  483.     for i := 1 to numOfLines do begin
  484. {$ifdef windows}
  485.        moveTo(dc, scrPoints[lines[i].fromP].sX, scrPoints[lines[i].fromP].sY);
  486.        lineTo(dc, scrPoints[lines[i].toP].sX, scrPoints[lines[i].toP].sY  );
  487. {$else}
  488.        line(scrPoints[lines[i].fromP].sX,
  489.             scrPoints[lines[i].fromP].sY,
  490.             scrPoints[lines[i].toP].sX,
  491.             scrPoints[lines[i].toP].sY);
  492. {$endif}
  493.     end; { for }
  494.     {it should be noted that calcPoint has to convert points to integers}
  495. end; {obj3d.paint}
  496.  
  497. (******************************************************************************
  498. *                                obj3d.readMe                                 *
  499. ******************************************************************************)
  500. procedure obj3d.readMe;
  501. var
  502.     tmp1,tmp2  : real;
  503.     i,j        : byte;
  504. begin
  505.        read(elementFile, tmp1);
  506.        numOfPoints := trunc(tmp1);
  507.        for j := 1 to numOfPoints do begin
  508.            read(elementFile, points[j].x);
  509.            read(elementFile, points[j].y);
  510.            read(elementFile, points[j].z);
  511.        end; {for}
  512.        read(elementFile, tmp1);
  513.        numOfLines := trunc(tmp1);
  514.        for j := 1 to numOfLines do begin
  515.            read(elementFile, tmp1, tmp2);
  516.            lines[j].fromP := trunc(tmp1);
  517.            lines[j].toP   := trunc(tmp2);
  518.        end; {for}
  519. end; {obj3d.readMe}
  520.  
  521. (******************************************************************************
  522. *                                obj3d.writeMe                                *
  523. ******************************************************************************)
  524. procedure obj3d.writeMe;
  525. var
  526.     tmp1,tmp2  : real;
  527.     i,j        : byte;
  528. begin
  529.        tmp1 := numOfPoints;
  530.        write(elementFile, tmp1);
  531.        for j := 1 to numOfPoints do begin
  532.            write(elementFile, points[j].x);
  533.            write(elementFile, points[j].y);
  534.            write(elementFile, points[j].z);
  535.        end; {for}
  536.        tmp1 := numOfLines;
  537.        write(elementFile, tmp1);
  538.        for j := 1 to numOfLines do begin
  539.            tmp1 := lines[j].fromP;
  540.            tmp2 := lines[j].toP;
  541.            write(elementFile, tmp1, tmp2);
  542.        end;
  543. end; {obj3d.writeMe}
  544.  
  545. (*******************************************************************************
  546. *                             obj3d.calcLocation                               *
  547. *******************************************************************************)
  548. procedure obj3d.calcLocation;
  549. var
  550.        ce : point3d;
  551.        p  : point3d;
  552.        i  : integer;
  553. begin
  554.        ce := zeroPoint; { (0, 0, 0) -> ce }
  555.        for i := 1 to numOfPoints do begin
  556.                myCtm.transform(p, points[i]);
  557.                ce.x := ce.x + p.x;
  558.                ce.y := ce.y + p.y;
  559.                ce.z := ce.z + p.z;
  560.        end; {for}
  561.        location.x := ce.x / numOfPoints;
  562.        location.y := ce.y / numOfPoints;
  563.        location.z := ce.z / numOfPoints;
  564. end; {obj3d.calcLocation}
  565.  
  566. (*******************************************************************************
  567. *                             Obj3d.setToOrigin                                *
  568. *******************************************************************************)
  569. procedure Obj3d.setToOrigin;
  570. var
  571.        i : integer;
  572.        p : point3d;
  573. begin
  574.     goto3dPos(0, 0, 0);
  575.     for i := 1 to numOfPoints do begin
  576.            myCtm.transform(p, points[i]);
  577.            points[i] := p;
  578.     end; {for}
  579.     scrPntUpdt := False; (** Instead of that THING above **)
  580.     myCtm.setUnit;
  581.     location := zeroPoint;
  582. end; {BaseObject.setToOrign}
  583.  
  584. (*******************************************************************************
  585. *                              ComplexObj.Open                                 *
  586. *******************************************************************************)
  587. constructor ComplexObj.Open;
  588. begin
  589.     BaseObject.Open(myName, color);
  590.     numOfChilds := 0;
  591. end; {complexObj.open}
  592.  
  593. (*******************************************************************************
  594. *                             ComplexObj.CloseMe                               *
  595. *******************************************************************************)
  596. destructor ComplexObj.CloseMe;
  597. var
  598.        i : integer;
  599.  
  600. begin
  601.        for i := 1 to numOfChilds do
  602.                dispose(childs[i],closeMe);
  603.        baseObject.closeMe;
  604. end; {complexObj.closeMe}
  605.  
  606. (*******************************************************************************
  607. *                          ComplexObj.addSubObject                             *
  608. *******************************************************************************)
  609. function ComplexObj.addSubObject;
  610. var
  611.     ret_code : word;
  612. begin
  613.        if (numOfChilds >= maxSubObjects) then begin
  614.                addSubObject := 255; {signal error}
  615.                exit;
  616.        end;
  617.        inc(numOfChilds);
  618.        childs[numOfChilds] := new(obj3dPtr, open(myName, zeroPoint, myColor));
  619.        ret_code := childs[numOfChilds]^.load;
  620.        if (ret_code = 0) then begin
  621.                with refPoint do
  622.                        childs[numOfChilds]^.translate(round(x),
  623.                                                round(y), round(z));
  624.                ctms[numOfChilds].copy(childs[numOfChilds]^.myCtm);
  625.        end; {if ret_c..}
  626.        addSubObject := ret_code;
  627. end; {complexObj.addSubObject}
  628.  
  629. (*******************************************************************************
  630. *                       complexObj.updateScreenPoints                          * 
  631. *******************************************************************************)
  632. procedure complexObj.updateScreenPoints;
  633. var
  634.     i : integer;
  635. begin
  636.     for i := 1 to numOfChilds do begin
  637.        childs[i]^.myCtm.multiply_2(ctms[i], myCtm);
  638.        childs[i]^.updateScreenPoints;
  639.     end;
  640.     scrPntUpdt := True;
  641. end; {complexObj.updateScreenPoints}
  642.  
  643. (*******************************************************************************
  644. *                           complexObj.getChildPtr                             *
  645. *******************************************************************************)
  646. function complexObj.getChildPtr;
  647. begin
  648.        getChildPtr := childs[index];
  649. end; {complexObj.getChildPtr}
  650.  
  651. (*******************************************************************************
  652. *                           ComplexObj.rotateChild                             *
  653. *******************************************************************************)
  654. procedure ComplexObj.rotateChild;
  655. begin
  656.     with childs[child]^ do begin
  657.        myCtm.copy(ctms[child]);
  658.        rotate(axis, deg);
  659.        ctms[Child].copy(MyCtm);
  660.        myCtm.Multiply(Self.myCtm);
  661.     end;
  662. end; {complexObj.rotateChild}
  663.  
  664. (*******************************************************************************
  665. *                           ComplexObj.scaleChild                              *
  666. *******************************************************************************)
  667. procedure ComplexObj.scaleChild;
  668. begin
  669.     with childs[child]^ do begin
  670.        myCtm.copy(ctms[child]);
  671.        scale(axis, factor);
  672.        ctms[Child].copy(MyCtm);
  673.        myCtm.Multiply(Self.myCtm);
  674.     end;
  675. end; {complexObj.scaleChild}
  676.  
  677. (*******************************************************************************
  678. *                            ComplexObj.moveChild                              *
  679. *******************************************************************************)
  680. procedure ComplexObj.moveChild;
  681. begin
  682.     with childs[child]^ do begin
  683.        myCtm.copy(ctms[child]);
  684.        move(axis, by);
  685.        ctms[Child].copy(MyCtm);
  686.        myCtm.Multiply(Self.myCtm);
  687.     end;
  688. end; {complexObj.moveChild}
  689.  
  690. (******************************************************************************
  691. *                              complexObj.paint                               *
  692. ******************************************************************************)
  693. procedure complexObj.paint;
  694. var
  695.        i : integer;
  696. begin
  697.     if (not(scrPntUpdt)) then
  698.        updateScreenPoints;
  699.     for i := 1 to numOfChilds do
  700. {$ifdef WINDOWS}
  701.        childs[i]^.paint(dc);
  702. {$else}
  703.        childs[i]^.paint;
  704. {$endif}
  705. end; {complexObj.paint}
  706.  
  707. (******************************************************************************
  708. *                             complexObj.writeMe                              *
  709. ******************************************************************************)
  710. procedure complexObj.writeMe;
  711. var
  712.        i : integer;
  713.        r : real;
  714. begin
  715.        r := 0.0 + numOfChilds;
  716.        write(elementFile, r);
  717.        for i := 1 to numOfChilds do
  718.                childs[i]^.writeMe(elementFile); {let all the kids write themselvs}
  719. end; {complexObj.writeMe}
  720.  
  721. (******************************************************************************
  722. *                              complexObj.readMe                              *
  723. ******************************************************************************)
  724. procedure complexObj.readMe;
  725. var
  726.        i : integer;
  727.        r : real;
  728. begin
  729.        read(elementFile, r);
  730.        numOfChilds := round(r);
  731.        for i := 1 to numOfChilds do begin
  732.               childs[i] := new(Obj3dPtr, Open('Child', ZeroPoint, myColor));
  733.               childs[i]^.readMe(elementFile);
  734.               childs[i]^.calcLocation;
  735.               ctms[i].setUnit;
  736.        end; {for}
  737. end; {complexObj.readMe}
  738.  
  739. (******************************************************************************
  740. *                           complexObj.calcLocation                           *
  741. ******************************************************************************)
  742. procedure complexObj.calcLocation;
  743. var
  744.        i : integer;
  745. begin
  746.        location := zeroPoint;
  747.        for i := 1 to numOfChilds do
  748.                with childs[i]^ do begin
  749.                        calcLocation;
  750.                        self.location.x := location.x + self.location.x;
  751.                        self.location.y := location.y + self.location.y;
  752.                        self.location.z := location.z + self.location.z;
  753.                end; {with}
  754.        with location do begin
  755.                x := x / numOfChilds;
  756.                y := y / numOfChilds;
  757.                z := z / numOfChilds;
  758.        end; {with..}
  759. end; {complexObj.calclocation}
  760.  
  761. (******************************************************************************
  762. *                               complexObj.move                               *
  763. ******************************************************************************)
  764. procedure complexObj.move;
  765. var
  766.        i : integer;
  767. begin
  768. (*       for i := 1 to numOfChilds do
  769.                with childs[i]^ do
  770.                        case axis of
  771.                                x : location.x := location.x + by;
  772.                                y : location.y := location.y + by;
  773.                                z : location.z := location.z + by;
  774.                        end; {case}  *)
  775.        baseObject.move(axis, by);
  776. end; {complexObj.move}
  777.  
  778. (******************************************************************************
  779. *                              complexObj.rotate                              *
  780. ******************************************************************************)
  781. procedure complexObj.rotate;
  782. var
  783.        i : integer;
  784.        sint, cost : real;
  785. begin
  786. (*       cost := cos(deg / 180.0 * 3.1415926535897932385);
  787.        sint := sin(deg / 180.0 * 3.1415926535897932385);
  788.        for i := 1 to numOfChilds do
  789.                with childs[i]^ do
  790.                        case axis of
  791.                                x : begin
  792.                                        location.y := location.y * cost -
  793.                                                location.z * sint;
  794.                                        location.z := location.y * sint +
  795.                                                location.z * cost;
  796.                                end; {x}
  797.                                y : begin
  798.                                        location.x := location.x * cost +
  799.                                                location.z * sint;
  800.                                        location.z := location.z * cost -
  801.                                                location.x * sint;
  802.                                end; {y}
  803.                                z : begin
  804.                                        location.x := location.x * cost -
  805.                                                location.y * sint;
  806.                                        location.y := location.y * cost +
  807.                                                location.x * sint;
  808.                                end; {z}
  809.                        end; {case} *)
  810.        baseObject.rotate(axis, deg);
  811. end; {complexObj.rotate}
  812.  
  813. (******************************************************************************
  814. *                              complexObj.scale                               *
  815. ******************************************************************************)
  816. procedure complexObj.scale;
  817. var
  818.        i : integer;
  819. begin
  820. (*       for i := 1 to numOfChilds do
  821.                with childs[i]^ do
  822.                        case axis of
  823.                                x : location.x := location.x * factor;
  824.                                y : location.y := location.y * factor;
  825.                                z : location.z := location.z * factor;
  826.                        end; {case} *)
  827.        baseObject.scale(axis, factor);
  828. end; {complexObj.scale}
  829.  
  830. (******************************************************************************
  831. *                                    end.                                     *
  832. ******************************************************************************)
  833. end.
  834.